package com.abcode.nettyclient.client;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.serialization.ClassResolvers;
import io.netty.handler.codec.serialization.ObjectDecoder;
import io.netty.handler.codec.serialization.ObjectEncoder;
import io.netty.handler.timeout.IdleStateHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.UUID;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;


@Configuration
public class NettyClientConfig {
    public static String clientId= UUID.randomUUID().toString();
    private final String host = "localhost";
    private final int port = 9999;
    private Channel channel = null;

    @Bean
    public EventLoopGroup eventLoopGroup() {
        return new NioEventLoopGroup();
    }

    @Bean
    public Bootstrap bootstrap() {
        Bootstrap bootstrap = new Bootstrap();
        bootstrap.group(eventLoopGroup())
                .channel(NioSocketChannel.class)
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                        ChannelPipeline pipeline = ch.pipeline();
                        pipeline.addLast(new IdleStateHandler(20, 10, 0));
                        pipeline.addLast(new ObjectEncoder());
                        pipeline.addLast(new ObjectDecoder(ClassResolvers.cacheDisabled(null)));
                        pipeline.addLast(new NettyClientHandler2(NettyClientConfig.this));
                    }
                });
        return bootstrap;
    }

    @Bean
    public ChannelFuture channelFuture(Bootstrap bootstrap) throws InterruptedException {
        ChannelFuture channelFuture = bootstrap.connect(host, port).sync();
        channel = channelFuture.channel();
        return channelFuture;
    }

    public void reconnect() throws InterruptedException {
        System.out.println("重连开始------");
        if (channel != null && channel.isActive()) {
            System.out.println("连接正常，无需重连------");
            return;
        }
        ChannelFuture future = bootstrap().connect(host, port).sync();
        channel = future.channel();
        System.out.println("重连成功------");
    }

    public Channel getChannel() {
        return channel;
    }

    public void start() {
        ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
        executorService.scheduleAtFixedRate(() -> {
            System.out.println("check channel");
            try {

                if (channel == null || !channel.isActive()) {
                    reconnect();
                }

            } catch (InterruptedException e) {
                e.printStackTrace();
            }catch (Exception e){
                e.printStackTrace();
            }

        }, 0, 10, TimeUnit.SECONDS);
    }
}